package com.dayouzi.crawler_monitor.utils;


import com.dayouzi.crawler_monitor.base.exception.BusinessException;
import com.dayouzi.crawler_monitor.pojo.entity.MachineEnum;
import com.dayouzi.crawler_monitor.pojo.vo.ScheduledSituationVO;
import com.dayouzi.crawler_monitor.pojo.vo.ScheduledTaskVO;
import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;

import java.net.SocketTimeoutException;
import java.util.ArrayList;

/**
 * 定时任务接口访问工具类
 */
@Slf4j
public class ScheduleUtils {

    private static Gson gson = new Gson();

    /**
     * 根据服务器 + 定时任务名称，获取定时任务的id
     * @param machine
     * @param scheduledName
     * @return
     */
    public static Integer getScheduledId(String machine, String scheduledName) {
        try {
            // 根据枚举获取服务器id
            Integer machineId = MachineEnum.getMachineId(machine);
            if (machineId == 0) {
                throw new BusinessException("获取服务器id失败，请检查服务器ip是否正确");
            }

            // 访问接口
            String url = "http://192.168.1.221:8080/xxl-job-admin/jobinfo/pageList";
            Connection conn = Jsoup.connect(url);
            conn.header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            conn.header("Host", "192.168.1.221:8080");
            conn.header("Cookie", "XXL_JOB_LOGIN_IDENTITY=7b226964223a31362c22757365726e616d65223a22796f757169222c2270617373776f7264223a223630626634633864356639393665383661353836323661626632666665316532222c22726f6c65223a312c227065726d697373696f6e223a22227d");
            conn.data("jobGroup", String.valueOf(machineId));
            conn.data("triggerStatus", "-1");
            conn.data("start", "0");
            conn.data("length", "1000");
            conn.method(Connection.Method.POST).timeout(30000).ignoreContentType(true);
            Connection.Response response = request(conn, "utf-8", 5, 2000);
            String body = response.body(); // 有可能报空指针异常
            LinkedTreeMap<String, Object> ltm = gson.fromJson(body, LinkedTreeMap.class);
            ArrayList<LinkedTreeMap<String, Object>> list = (ArrayList<LinkedTreeMap<String, Object>>) ltm.get("data");
            for (LinkedTreeMap<String, Object> ele : list) {
                String jobDesc = (String) ele.get("jobDesc");
                if (scheduledName.equals(jobDesc)) {
                    Double id = (Double) ele.get("id");
                    return id.intValue();
                }
            }
        } catch (Exception e) {
            log.error("获取定时任务的id，服务器: " + machine + ", 任务名: " + scheduledName);
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 获取定时任务执行情况
     * @param taskVO
     * @return
     */
    public static ScheduledTaskVO getSituation(ScheduledTaskVO taskVO) {
        try {
            // 访问接口
            String url = "http://192.168.1.221:8080/xxl-job-admin/joblog/pageList";
            Connection conn = Jsoup.connect(url);
            conn.header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            conn.header("Host", "192.168.1.221:8080");
            conn.header("Cookie", "XXL_JOB_LOGIN_IDENTITY=7b226964223a31362c22757365726e616d65223a22796f757169222c2270617373776f7264223a223630626634633864356639393665383661353836323661626632666665316532222c22726f6c65223a312c227065726d697373696f6e223a22227d");
            conn.data("jobGroup", String.valueOf(taskVO.getMachineId()));
            conn.data("jobId", String.valueOf(taskVO.getScheduledId()));
            conn.data("logStatus", "-1");
            conn.data("filterTime", DateUtils.getTodayRange());
            conn.data("start", "0");
            conn.data("length", "10");
            conn.method(Connection.Method.POST).timeout(30000).ignoreContentType(true);
            Connection.Response response = request(conn, "utf-8", 5, 2000);
            String body = response.body(); // 有可能报空指针异常
            LinkedTreeMap<String, Object> ltm = gson.fromJson(body, LinkedTreeMap.class);
            ArrayList<LinkedTreeMap<String, Object>> list = (ArrayList<LinkedTreeMap<String, Object>>) ltm.get("data");
            ArrayList<ScheduledSituationVO> situationVOList = new ArrayList<>(); // 具体情况list
            for (LinkedTreeMap<String, Object> ele : list) {
                ScheduledSituationVO situationVO = new ScheduledSituationVO();
                Double triggerCode = (Double) ele.get("triggerCode");
                if (triggerCode.intValue() != 200) {
                    // 填充执行情况
                    situationVO.setStatus("执行失败");
                    // 填充执行时间
                    String triggerTime = (String) ele.get("triggerTime");
                    situationVO.setStatusTime(DateUtils.getISOTime(triggerTime));
                    situationVOList.add(situationVO);
                }
            }
            taskVO.setList(situationVOList);
            sleep(200);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("获取定时任务执行情况出错...");
        }
        return taskVO;
    }


    /**
     * 请求工具类,自定义重试次数和间隔时间
     *
     * @param conn
     * @param charset
     * @param retry
     * @param sleepTime
     * @return
     */
    private synchronized static Connection.Response request(Connection conn, String charset, int retry, int sleepTime) {
        conn.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36");
        for (int count = 1; count <= retry; count++) {
            try {
                return conn.execute().charset(charset);
            } catch (SocketTimeoutException ex) {//timeout
                log.error("获取网页请求超时 ... " + ex.getLocalizedMessage() + "，异常url：" + conn.request().url().toString());
                sleep(sleepTime);
            } catch (Exception ex) {
                sleep(sleepTime);
                log.error(ex.getLocalizedMessage() + "，异常url：" + conn.request().url().toString());
                continue;
            }
        }
        return null;
    }

    /**
     * 程序睡眠,单位毫秒
     *
     * @param sleepTime
     */
    private static void sleep(int sleepTime) {
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException ex) {
            log.error("【sleep方法】程序sleep时被异常唤醒！异常信息： "
                    + ex.getLocalizedMessage());
        }
    }

    public static void main(String[] args) {
        Integer scheduledId = ScheduleUtils.getScheduledId("192.168.1.225", "浙江省公共资源交易中心(政策新闻)");
        System.out.println(scheduledId);
    }

}
